local hide = "隐藏箭头"
local KEY = true

-- 仇恨距离和攻击距离
local TARGET_DIST_AUTO = {
	"WALRUS", "KNIGHT", "BISHOP", "ROOK", "SLURTLE",
	"SPAT", "WORM", "TALLBIRD",
	"ALTERGUARDIAN_PHASE1","ALTERGUARDIAN_PHASE2",
	"ALTERGUARDIAN_PHASE3",
	-- BOSS
	"MINOTAUR", 
}

local ATTACK_RANGE_AUTO = {
	"TALLBIRD", "BUZZARD", "TEENBIRD", "SQUID","SLURTLE",
	"SPIDER_WATER", "TENTACLE_PILLAR_ARM","WORM",
	"CATCOON","SLURPER","WALRUS",
	-- BOSS
	"MOSSLING","BEEGUARD","MOOSE","BEARGER","BEEQUEEN",
	"DEERCLOPS","LORDFRUITFLY","WARG","SPIDERQUEEN","MALBATROSS",
	"KLAUS","DRAGONFLY",

	-- 吞噬距离 / 停止攻击距离
	"EYEPLANT",
}

local function apply(prefab, color, range, always, add, quick)
	local prefab = string.lower(prefab)
	local item = string.format("atkr_%s", range)
	AddPrefabPostInit(prefab, function(inst)
		local flushTime = quick and 0.1 or 1
		inst:DoPeriodicTask(flushTime, function()
			if not inst[item] then
				inst[item] = GLOBAL.SpawnPrefab("hrange"):setVisable(false):setParentScale(inst, range+add):setColor(color)
				-- TheSim:CountEntities(x, y, z, 2, nil, {"tallbird"})
				if prefab == "tallbird" then
					inst[item]:AddTag(prefab)
				end
			else
				if not KEY then
					inst[item]:setVisable(false):setParentHighLight(inst, color)
					return
				end
				if GetAggro(inst) == GLOBAL.ThePlayer then
					inst[item]:setParentHighLight(inst, true):setVisable(true)
				elseif always then
					inst[item]:setVisable(true):setColor(color)
				else
					inst[item]:setParentHighLight(inst, color)
					-- local leader = GetLeader(inst)
					if GLOBAL.ThePlayer and inst:GetPosition():DistSq(GLOBAL.ThePlayer:GetPosition()) > 9*range*range 
					or GetLeader(inst)
					then
						inst[item]:setVisable(false)
					else
						inst[item]:setVisable(true)
					end
				end
			end
		end)
	end)
end


for _, animals in pairs(GLOBAL.rangeTable.attack_range) do
	for _, prefab in pairs(animals.prefabs)do
		for _, circle in pairs(animals.rotary)do
			apply(prefab, circle[1], circle[2], animals.always, 0.5)
		end
	end
end

for _, animals in pairs(GLOBAL.rangeTable.target_range) do
	for _, prefab in pairs(animals.prefabs)do
		for _, circle in pairs(animals.rotary)do
			apply(prefab, circle[1], circle[2], false, 0, animals.quick)
		end
	end
end

for _,prefab in pairs(TARGET_DIST_AUTO) do
	local prefab = string.upper(prefab)
	local range = GLOBAL.TUNING[string.format("%s_TARGET_DIST", prefab)]
	if range then
		apply(prefab, "blue", range, false, 0)
	end
end

for _,prefab in pairs(ATTACK_RANGE_AUTO) do
	local prefab = string.upper(prefab)
	-- sb
	local range = GLOBAL.TUNING[string.format("%s_ATTACK_DIST", prefab)] 
		or GLOBAL.TUNING[string.format("%s_HIT_RANGE", prefab)]
		or GLOBAL.TUNING[string.format("%s_ATTACK_RANGE", prefab)]
		or GLOBAL.TUNING[string.format("%s_ATTACKRANGE", prefab)]
	if range then
		apply(prefab, "blue", range, false, 0.5)
	end
end


local function animal_track(inst)
	inst:DoPeriodicTask(0.5, function()
		if not KEY then return end
		if inst and inst:IsValid() and inst.Transform then
			local x,y,z = inst.entity:LocalToWorldSpace(0,0,-40)
			local old_dirtpile = GLOBAL.TheSim:FindEntities(x,0,z, 10, {"dirtpile"}, { "locomotor", "INLIMBO" })
			GLOBAL.SpawnPrefab("huxi_arrow"):setColor("BLUE"):ping(inst, old_dirtpile[1])
		end
	end)
end
-- 保持追踪
-- 追踪的物体保持高亮, 且人物脚下有箭头指示
local Tracks = {}
local function goAway(arrow, color)
	GLOBAL.SpawnPrefab("huxi_arrow"):setColor(color):pingPos(GLOBAL.ThePlayer:GetPosition(), arrow.lastPos)
	arrow:Hide()
end
local function getColor(inst)
	return inst.prefab and GLOBAL.rangeTable.track_range[inst.prefab] or "RED"
end
local function keep_track(world)
	world:DoPeriodicTask(.01, function()
		if not KEY or KEY == hide then return end
		for inst,arrow in pairs(Tracks)do
			arrow:collect(GLOBAL.ThePlayer, inst)
			-- 距离过远
			if not inst:IsValid() then
				-- goAway(arrow)	-- 不必炫技
				arrow:Hide()
				Tracks[inst] = nil
			else
				if inst:HasTag("INLIMBO") then
					arrow:Hide()
				else
					arrow.lastPos = inst:GetPosition()
					local dist = math.sqrt(arrow:GetPosition():DistSq(arrow.lastPos))
					-- 距离过近
					if not arrow.dist_lock and dist < 20  then
						arrow.dist_lock = true
						goAway(arrow, getColor(inst))
					-- 距离偏远
					elseif arrow.dist_lock and dist > 36 then
						arrow.dist_lock = false
						arrow:Show()
					end
				end
			end
		end
	end)
end


for prefab, color in pairs(GLOBAL.rangeTable.track_range)do
	AddPrefabPostInit(prefab, function(inst)
		inst:DoTaskInTime(1, function()
			Tracks[inst] = GLOBAL.SpawnPrefab("huxi_arrow"):setColor(color):hide()
			if KEY == true and inst:IsValid() then
				inst.AnimState:SetLightOverride(1)
				Tracks[inst]:show()
			end
		end)
	end)
end


AddPrefabPostInit("world", function(inst)
	inst:ListenForEvent("playeractivated", keep_track)
end)
-- 脚印追踪
AddPrefabPostInit("animal_track",animal_track)

local Arrows = {}
for _,prefab in pairs(GLOBAL.rangeTable.starfish_range)do
	AddPrefabPostInit(prefab,function(inst)
		inst:DoPeriodicTask(0.4, function()
			if KEY and inst.GUID then
				local id = string.format("Huxi_%s", inst.GUID)
				if not Arrows[id] then
					Arrows[id] = SpawnMark(inst)
				end
			end
		end)
	end)
end

local function ClearArrows()
	for id,mark in pairs(Arrows)do
		for _,inst in pairs(mark)do
			inst:Remove()
		end
	end
	Arrows = {}
	for inst,arrow in pairs(Tracks)do
		if inst:IsValid() then
			inst.AnimState:SetLightOverride(0)
			goAway(arrow, getColor(inst))
		end
	end
end

local function ShowArrows()
	for inst,arrow in pairs(Tracks)do
		if inst:IsValid() then
			inst.AnimState:SetLightOverride(1)
			arrow:Show()
		end
	end
end


local Data = "ATK_DIST"

local function OnWorldPostInit(inst)
    inst:ListenForEvent("playeractivated", function()
        KEY = LoadModData(Data)
        if type(KEY) == "nil" then
            KEY = true
        end
    end)
end
AddPrefabPostInit("world", OnWorldPostInit)

local function switchKEY()
	if KEY == hide then
		KEY = false
		-- ClearArrows()				-- 其实这一步可以省了
	elseif KEY == false then
		KEY = true
		ShowArrows()
	else
		KEY = hide
		ClearArrows()
	end
	
	TIP("攻击范围", "pink", KEY)
	SaveModData(Data, KEY)
end

if GetModConfigData("sw_attack_dist") == "biubiu" then
	DEAR_BTNS:AddDearBtn(GLOBAL.GetInventoryItemAtlas("alterguardianhat_lastprism.tex"), "alterguardianhat_lastprism.tex", "攻击范围", "慕斯专属功能", false,	-- 测试阶段, 不要关
	 switchKEY)
end
	
AddBindBtn("sw_attack_dist", switchKEY)